<?php
declare (strict_types=1);

use Template\SmartAdapter;
use Yaf\Dispatcher;
use Yaf\Loader;
use Illuminate\Container\Container;
use Illuminate\Database\Capsule\Manager as Capsule;
use Illuminate\Events\Dispatcher as EventDispatcher;
use Yaf\Registry;

class Bootstrap extends Yaf\Bootstrap_Abstract{

    /**
     * 初始化composer自动加载
     * @return void
     */
    public function _initComposerAutoload(): void
    {
        $autoload = __ROOT__ . '/vendor/autoload.php';
        if (file_exists($autoload)) {
            Loader::import($autoload);
        }
    }

    /**
     * 初始化配置
     * @param Dispatcher $dispatcher
     * @return void
     */
    public function _initConfig(Dispatcher $dispatcher): void
    {
        $config = Yaf\Application::app()->getConfig();
        Yaf\Registry::set("config", $config);
        $dispatcher->getInstance()->disableView();
    }

    /**
     * 初始化错误处理
     * @param Dispatcher $dispatcher
     * @return void
     */
    public function _initErrorHandler(Dispatcher $dispatcher): void
    {
        $dispatcher->catchException(false);
        $dispatcher->throwException(false);
        $dispatcher->setErrorHandler(function($errno, $errMessage, $errFile, $errLine) {
            if (error_reporting() === 0) return;
            throw new ErrorException($errMessage, 50001, $errno, $errFile, $errLine);
        }, E_ALL ^E_NOTICE);
    }

    /**
     * 初始化数据库连接
     * @return void
     */
    public function _initDb(): void
    {
        $dbConfig = Config::get("db");
        $capsule = new Capsule;
        // 创建链接
        $capsule->addConnection($dbConfig);
        $capsule->setEventDispatcher(new EventDispatcher(new Container));
        // 设置全局静态可访问
        $capsule->setAsGlobal();
        // 启动Eloquent
        $capsule->bootEloquent();
        // 设置Eloquent的日志记录器
        $capsule->getConnection()->enableQueryLog();
        $capsule->getConnection()->setEventDispatcher(new EventDispatcher(new Container));
        $capsule->getConnection()->listen(function ($sql) {
            foreach ($sql->bindings as $i => $binding) {
                if ($binding instanceof DateTime) {
                    $sql->bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
                } else {
                    if (is_string($binding)) {
                        $sql->bindings[$i] = "'$binding'";
                    }
                }
            }
            $query = str_replace(array('%', '?'), array('%%', '%s'), $sql->sql);
            $query = vsprintf($query, $sql->bindings);
            // 将SQL语句和执行时间（秒）写入日志文件
            Log::info($query." time:".$sql->time);
        });
    }

    /**
     * 注册插件
     * @param Dispatcher $dispatcher
     * @return void
     */
    public function _initPlugin(Dispatcher $dispatcher): void
    {
        $dispatcher->registerPlugin(new FormPlugin());
        $dispatcher->registerPlugin(new ExceptionHandlerPlugin());
    }

    /**
     * 初始化视图
     * @param Dispatcher $dispatcher
     * @return void
     * @throws \Smarty\Exception
     */
    public function _initView(Dispatcher $dispatcher): void
    {
        $view= new SmartAdapter(null, Registry::get("config")->get("smarty")->toArray());
        $dispatcher::getInstance()->setView($view);
        //设置默认不渲染模板
        $dispatcher->getInstance()->disableView();
    }

    /**
     * 初始化默认模块
     * @param Dispatcher $dispatcher
     * @return void
     */
    public function _initDefaultName(Dispatcher $dispatcher): void
    {
        $dispatcher->setDefaultModule("Index")
            ->setDefaultController("Index")
            ->setDefaultAction("index");
    }

    /**
     * 处理化路由配置
     * @param Dispatcher $dispatcher
     * @return void
     */
    public function _initRoutes(Dispatcher $dispatcher): void
    {
    }
}
